package com.prj.ufdm.core.util;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** 
* @Description: Request Http 工具
* @date 2018年3月20日 
* @author 胡义振
*/
public class UfdmRequestHttpUtil 
{
	private static Logger logger = LoggerFactory.getLogger(UfdmRequestHttpUtil.class);

	/**
	 * 描述: POST 流提交(提交JSON/XML/字符串等)
	 * @auther 胡义振
	 * @date 2018-03-20 
	 * @param reqUrl  请求地址
	 * @param headMap 请求头信息
	 * @param content 请求内容
	 * @param encode  编码
	 * @return
	 */
	public static String postStream(String reqUrl, Map<String,String> reqHeadMap,String reqContent, String encode) throws Exception 
	{
		HttpURLConnection urlCon = null;
		OutputStream out = null;
		BufferedReader in = null;
		StringBuffer result = new StringBuffer();
		try
		{
			URL url = new URL(reqUrl);
			urlCon = (HttpURLConnection) url.openConnection();
			// 设置允许输出
			urlCon.setDoOutput(true);
			urlCon.setDoInput(true);
            // 设置不用缓存
			urlCon.setUseCaches(false);
			urlCon.setRequestMethod("POST");
			urlCon.setRequestProperty("Connection", "Keep-Alive");
			urlCon.setRequestProperty("Charset", "UTF-8");
			
			//转换为字节数组
            byte[] data = (reqContent.toString()).getBytes();
            // 设置文件长度
            urlCon.setRequestProperty("Content-Length", String.valueOf(data.length));
            urlCon.setRequestProperty("content-type", "application/json");
            
			if(reqHeadMap!=null){
				String tempKey;
				String tempValue;
				Set<String> headKey = reqHeadMap.keySet();
				Iterator<String> it = headKey.iterator();
				while(it.hasNext()){
					tempKey = it.next();
					tempValue = reqHeadMap.get(tempKey)!=null ? URLEncoder.encode(reqHeadMap.get(tempKey),encode) : "";
					urlCon.setRequestProperty(tempKey, tempValue);
				}
			}
			out = urlCon.getOutputStream();
			out.write(reqContent.getBytes(encode));
			out.flush();
			in = new BufferedReader(new InputStreamReader(urlCon.getInputStream(), encode));
			String line = "";
			while ((line = in.readLine()) != null)
			{
				result.append(line);
			}
		}
		catch (Exception e)
		{
			logger.info("\n 调用 Request Stream 出现异常 -- Request Url:" + reqUrl + "  Request Param:"+reqContent); 
			e.printStackTrace();
			throw new Exception();
		}
		finally
		{
			try
			{
				if (out != null)
				{
					out.close();
					out = null;
				}
				if (in != null)
				{
					in.close();
					in = null;
				}
				if (urlCon != null)
				{
					urlCon.disconnect();
					urlCon = null;
				}
			}
			catch (Exception ex)
			{

			}
		}
		return result!=null?result.toString():"";
    }
	
	/**
	 * 描述: POST 参数提交
	 * @auther 胡义振
	 * @date 2018-03-20 
	 * @param reqUrl      请求地址
	 * @param headMap     请求头信息
	 * @param reqParamMap 请求参数
	 * @param encode      编码
	 * @return
	 */
	public static String postParam(String reqUrl, Map<String,String> reqHeadMap, Map<String,String> reqParamMap, String encode)  throws Exception 
	{
		HttpURLConnection urlCon = null;
		PrintWriter out = null;
		BufferedReader in = null;
		StringBuffer result = new StringBuffer();
		try
		{
			URL url = new URL(reqUrl);
			urlCon = (HttpURLConnection)url.openConnection();
			// 设置通用的请求属性
			urlCon.setRequestMethod("POST");
			urlCon.setRequestProperty("Accept", "*/*;charset="+encode);
			urlCon.setRequestProperty("Charset", encode);
			urlCon.setRequestProperty("Content-type", "application/x-www-form-urlencoded;charset="+encode);
			if(reqHeadMap!=null) {
				String tempKey;
				String tempValue;
				Set<String> headKey = reqHeadMap.keySet();
				Iterator<String> it = headKey.iterator();
				while(it.hasNext()){
					tempKey = it.next();
					tempValue = reqHeadMap.get(tempKey)!=null ? URLEncoder.encode(reqHeadMap.get(tempKey),encode) : "";
					urlCon.setRequestProperty(tempKey, tempValue);
				}
			}
			urlCon.setDoOutput(true);
			out = new PrintWriter(urlCon.getOutputStream());
			out.print(UfdmMapUtil.mapToUrlParam(reqParamMap,encode));
			out.flush();
			
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(urlCon.getInputStream(),encode));
			String line = "";
			while ((line = in.readLine()) != null)
			{
				result.append(line);
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				if (out != null)
				{
					out.close();
					out = null;
				}
				if (in != null)
				{
					in.close();
					in = null;
				}
				if (urlCon != null)
				{
					urlCon.disconnect();
					urlCon = null;
				}
			}
			catch (Exception ex)
			{

			}
		}
		return result!=null?result.toString():"";
	}
	
	
	/**
	 * 描述: POST 参数提交
	 * @auther 胡义振
	 * @date 2018-03-20 
	 * @param reqUrl      请求地址
	 * @param headMap     请求头信息
	 * @param reqParamMap 请求参数
	 * @param encode      编码
	 * @return
	 */
	public static String postApiParam(String reqUrl, Map<String,String> reqHeadMap, Map<String,String> reqParamMap, String encode)  throws Exception 
	{
		HttpURLConnection urlCon = null;
		PrintWriter out = null;
		BufferedReader in = null;
		StringBuffer result = new StringBuffer();
		try
		{
			URL url = new URL(reqUrl);
			urlCon = (HttpURLConnection)url.openConnection();
			// 设置通用的请求属性
			urlCon.setRequestMethod("POST");
			urlCon.setRequestProperty("Accept", "*/*;charset="+encode);
			urlCon.setRequestProperty("Charset", encode);
			urlCon.setRequestProperty("Content-type", "application/json;charset="+encode);
			if(reqHeadMap!=null) {
				String tempKey;
				String tempValue;
				Set<String> headKey = reqHeadMap.keySet();
				Iterator<String> it = headKey.iterator();
				while(it.hasNext()){
					tempKey = it.next();
					tempValue = reqHeadMap.get(tempKey)!=null ? URLEncoder.encode(reqHeadMap.get(tempKey),encode) : "";
					urlCon.setRequestProperty(tempKey, tempValue);
				}
			}
			urlCon.setDoOutput(true);
			out = new PrintWriter(urlCon.getOutputStream());
			out.print(UfdmMapUtil.mapToUrlParam(reqParamMap,encode));
			out.flush();
			
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(urlCon.getInputStream(),encode));
			String line = "";
			while ((line = in.readLine()) != null)
			{
				result.append(line);
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				if (out != null)
				{
					out.close();
					out = null;
				}
				if (in != null)
				{
					in.close();
					in = null;
				}
				if (urlCon != null)
				{
					urlCon.disconnect();
					urlCon = null;
				}
			}
			catch (Exception ex)
			{

			}
		}
		return result!=null?result.toString():"";
	}
	
	
	/**
	 * 描述: POST 提交文件
	 * @auther 胡义振
	 * @date 2018-03-20 
	 * @param reqUrl      请求地址
	 * @param headMap     请求头信息
	 * @param reqParamMap 请求参数
	 * @param reqFileMap  请求文件
	 * @param encode      编码
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static String postFile(String reqUrl, Map<String,String> reqHeadMap, Map<String,String> reqParamMap, Map<String, File> reqFileMap, String encode) {
		HttpURLConnection urlCon = null;
		OutputStream out = null;
		InputStream in = null;
		StringBuffer result = new StringBuffer();
		String BOUNDARY = "---------------------------123821742118716"; //boundary就是request头和上传文件内容的分隔符
		try {
			URL url = new URL(reqUrl);
			urlCon = (HttpURLConnection) url.openConnection();
			urlCon.setConnectTimeout(5000);
			urlCon.setReadTimeout(30000);
			urlCon.setDoOutput(true);
			urlCon.setDoInput(true);
			urlCon.setUseCaches(false);
			urlCon.setRequestMethod("POST");
			urlCon.setRequestProperty("Connection", "Keep-Alive");
			urlCon.setRequestProperty("User-Agent","Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)");
			urlCon.setRequestProperty("Content-Type","multipart/form-data; boundary=" + BOUNDARY);
			if(reqHeadMap!=null) {
				String tempKey;
				String tempValue;
				Set<String> headKey = reqHeadMap.keySet();
				Iterator<String> it = headKey.iterator();
				while(it.hasNext()){
					tempKey = it.next();
					tempValue = reqHeadMap.get(tempKey)!=null ? URLEncoder.encode(reqHeadMap.get(tempKey),encode) : "";
					urlCon.setRequestProperty(tempKey, tempValue);
				}
			}
			out = new DataOutputStream(urlCon.getOutputStream());
			// 提交参数
			if (reqParamMap != null) {
				StringBuffer strBuf = new StringBuffer();
				Iterator iter = reqParamMap.entrySet().iterator();
				while (iter.hasNext()) {
					Map.Entry entry = (Map.Entry) iter.next();
					String inputName = (String) entry.getKey();
					String inputValue = (String) entry.getValue();
					if (inputValue == null) {
						continue;
					}
					strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
					strBuf.append("Content-Disposition: form-data; name=\""	+ inputName + "\"\r\n\r\n");
					strBuf.append(inputValue);
				}
				out.write(strBuf.toString().getBytes());
			}
			// 提交文件
			if (reqFileMap != null) {
				Iterator iter = reqFileMap.entrySet().iterator();
				while (iter.hasNext()) {
					Map.Entry entry = (Map.Entry) iter.next();
					String inputName = (String) entry.getKey();
					File inputFile = (File) entry.getValue();
					String filename = inputFile.getName();
					
					StringBuffer strBuf = new StringBuffer();
					strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n");
					strBuf.append("Content-Disposition: form-data; name=\""	+ inputName + "\"; filename=\"" + filename	+ "\"\r\n");
					strBuf.append("Content-Type:application/octet-stream\r\n\r\n");

					out.write(strBuf.toString().getBytes());

					in = new DataInputStream(new FileInputStream(inputFile));
					int bytes = 0;
					byte[] bufferOut = new byte[1024];
					while ((bytes = in.read(bufferOut)) != -1) {
						out.write(bufferOut, 0, bytes);
					}
					in.close();
				}
			}

			byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
			out.write(endData);
			out.flush();
			out.close();

			BufferedReader reader = new BufferedReader(new InputStreamReader(urlCon.getInputStream(),encode));
			String line = null;
			while ((line = reader.readLine()) != null) {
				result.append(line).append("\n");
			}
			
		} catch (Exception e) {
			
			logger.info("\n 调用 Request Stream 出现异常 -- Request Url:" + reqUrl + "  Request Param:"+reqFileMap); 
			
			e.printStackTrace();
			
		} finally {
			try
			{
				if (out != null)
				{
					out.close();
					out = null;
				}
				if (in != null)
				{
					in.close();
					in = null;
				}
				if (urlCon != null)
				{
					urlCon.disconnect();
					urlCon = null;
				}
			}
			catch (Exception ex)
			{

			}
		}
		return result!=null?result.toString():"";
	}
	
	public static void main(String args [] ){
		try
		{
			String reqUrl = "http://115.233.221.131:27401/api/file/upload";
			Map<String,String> reqHeadMap = new HashMap<String,String>();
			reqHeadMap.put("Auth-User-Token", "88B7F80A99904B8B9548AF0A6A056AF4");
			Map<String,String> reqParamMap = new HashMap<String,String>();
			reqParamMap.put("aliases", "测试111图片");
			Map<String, File> reqFileMap = new HashMap<String, File>();
	        
			// 通过流文件读取
	        String file2Path = "D:\\newdown\\111.png";
	        File file = new File(file2Path);
			reqFileMap.put("file", file);
			
			String encode = "utf-8";
			System.out.println(UfdmRequestHttpUtil.postFile(reqUrl,reqHeadMap,reqParamMap,reqFileMap,encode));
			
			
		}
		catch(Exception er){
			er.printStackTrace();
		}
	}
	
}
